---
--类名: WeatherSystem.lua
--创建日期: 2016-8-10
--创建人: 陈小虎
--功能描述: 天气系统
--修改内容:
--修改日期: 2018-12-3
--修改人: galileoliu
--修改备注: 
--
local WeatherSystem = class("WeatherSystem")

function WeatherSystem:ctor()
	self:resetData()
end

function WeatherSystem:setMap(map)
	self._map = map
end

function WeatherSystem:getMap()
	return self._map
end

function WeatherSystem:stopCurAction()
	if self._curAction then
		if self._map then
			self._map:stopAction(self._curAction)
		end
		self._curAction = nil
	end
end

function WeatherSystem:resetData()
	self._ids = {}
	self._map = nil
	self._playMode = 0
	self._curIndex = 1
	self._state = nil
	self:resetWeatherData()
end	

function WeatherSystem:resetWeatherData()
	self._scriptHandler = nil
	self._preScriptHandler = nil
	self._rearScriptHandler = nil
	self._keepTime = nil
end

function WeatherSystem:initWeatherSystem()
	if not self._map then return end

	self:closeWeather()

	local mapId = MapManager:getMapId()
	local mapConfig = GD:queryMapById(mapId)
	if not mapConfig or not mapConfig.weather then
		return
	end

	-- 0 顺序播放 1 随机播放 -1 单个循环播放
	self._playMode = tonumber(mapConfig.weathertype) or 0

	self._ids = string.split(mapConfig.weather,"|")
	self._curIndex = 1

	self:resetScriptHandler()
end

local function parseScripts(name)
	if not name then return end
	local path = "scripts.weather." .. name
	local script = app:loadResScript(path)
	return script
end

function WeatherSystem:resetScriptHandler()
	self:resetWeatherData()
	self:stopCurAction()

	local len = #self._ids
	if len <= 0 then return end

	local index = math.random(1, len)
	local weatherId = tonumber(self._ids[index])
	if self._playMode == 0 then--顺序
		weatherId = tonumber(self._ids[self._curIndex])
		local nextIndex = self._curIndex + 1
		if nextIndex > len then
			nextIndex = 1
		end
		self._curIndex = nextIndex
	elseif self._playMode == 1 then--随机

	elseif self._playMode == -1 then--单个循环
		weatherId = tonumber(self._ids[1])
	end

	-- print("WeatherSystem:resetScriptHandler --------- ")
	-- print("WeatherSystem:resetScriptHandler --------- weatherId = ",weatherId)
	-- dump(self._ids)

	local weatherConfig = GD:queryWeatherById(weatherId)
	if weatherConfig and weatherConfig.ID then
		local script = parseScripts(weatherConfig.script)
		self._scriptHandler = script
		local keepTimeStr = weatherConfig.keeptime
		local minSecond = 0
		local maxSecond = 0
		if keepTimeStr then
			local timeArray = string.split(keepTimeStr,"|")
			if #timeArray >= 2 then
				minSecond = tonumber(timeArray[1]) or 0
				maxSecond = tonumber(timeArray[2]) or 0
			end
		end

		local preMinSecond = 0
		local preMaxSecond = 0
		local preId = weatherConfig.beforeweather
		if preId then
			local preConfig = GD:queryWeatherById(preId)
			if preConfig and preConfig.ID then
				self._preScriptHandler = parseScripts(preConfig.script)
				local preKeepTimeStr = preConfig.keeptime
				if preKeepTimeStr then
					local timeArray = string.split(preKeepTimeStr,"|")
					if #timeArray >= 2 then
						preMinSecond = tonumber(timeArray[1]) or 0
						preMaxSecond = tonumber(timeArray[2]) or 0
					end
				end
			end
		end

		local rearMinSecond = 0
		local rearMaxSecond = 0
		local rearId = weatherConfig.afterweather
		if rearId then
			local rearConfig = GD:queryWeatherById(rearId)
			if rearConfig and rearConfig.ID then
				self._rearScriptHandler = parseScripts(rearConfig.script)
				local rearKeepTimeStr = rearConfig.keeptime
				if rearKeepTimeStr then
					local timeArray = string.split(rearKeepTimeStr,"|")
					if #timeArray >= 2 then
						rearMinSecond = tonumber(timeArray[1]) or 0
						rearMaxSecond = tonumber(timeArray[2]) or 0
					end
				end
			end
		end

		self._keepTime =
		{
			preMin = preMinSecond,
			preMax = preMaxSecond,
			min = minSecond,
			max = maxSecond,
			rearMin = rearMinSecond,
			rearMax = rearMaxSecond,
		}
	end
end

function WeatherSystem:playWeather(forceMode)
	if not forceMode and not UD.setting:isAutoPlayWeather() then
		return
	end
	self._state = "play"

	local keepTime = self._keepTime
	if not keepTime then return end

	local preTime = math.random(keepTime.preMin,keepTime.preMax) 
	local time = math.random(keepTime.min,keepTime.max)
	local rearTime = math.random(keepTime.rearMin,keepTime.rearMax)

	-- print("playWeather  preTime = ",preTime)
	-- print("playWeather  time = ",time)
	-- print("playWeather  rearTime = ",rearTime)

	local function startRearWeather()
		local fadeTime = 0
		local rearScriptHandler = self._rearScriptHandler
		if rearScriptHandler and rearScriptHandler.start then
			rearScriptHandler.start({map = self._map})
			fadeTime = rearScriptHandler.fadeTime or 0
		end

		local function start()
			local action = cc.Sequence:create(cc.DelayTime:create(rearTime),cc.CallFunc:create(function()
				self._map:fadeOutWeatherNodes(function()
					self:resetScriptHandler()
					self:playWeather()
				end,fadeTime)
				self._curAction = nil
			end))
			self._curAction = action
			self._map:runAction(action)
		end

		if fadeTime == 0 then
			start()
		else
			self._map:fadeInWeatherNodes(start,fadeTime)
		end
	end

	local function startWeather()
		local fadeTime = 0
		local scriptHandler = self._scriptHandler
		if scriptHandler and scriptHandler.start then
			scriptHandler.start({map = self._map})
			fadeTime = scriptHandler.fadeTime or 0
		end

		local function start()
			local action = cc.Sequence:create(cc.DelayTime:create(time),cc.CallFunc:create(function()
				self._map:fadeOutWeatherNodes(function()
					startRearWeather()
				end,fadeTime)
			end))
			self._curAction = action
			self._map:runAction(action)
		end

		if fadeTime == 0 then
			start()
		else
			self._map:fadeInWeatherNodes(start,fadeTime)
		end
	end

	local function startPreWeather()
		local fadeTime = 0
		local preScriptHandler = self._preScriptHandler
		if preScriptHandler and preScriptHandler.start then
			preScriptHandler.start({map = self._map})
			fadeTime = preScriptHandler.fadeTime or 0
		end

		local function start()
			local action = cc.Sequence:create(cc.DelayTime:create(preTime),cc.CallFunc:create(function()
				self._map:fadeOutWeatherNodes(function()
					startWeather()
				end,fadeTime)
			end))
			self._curAction = action
			self._map:runAction(action)
		end

		if fadeTime == 0 then
			start()
		else
			self._map:fadeInWeatherNodes(start, fadeTime)
		end
	end

	startPreWeather()
end

function WeatherSystem:closeWeather()
	self._state = "close"
	if cc.isAlive(self._map) then
		self._map:clearWeatherNodes()
	end
	self:resetWeatherData()
	self:stopCurAction()
end

function WeatherSystem:restartWeather(forceMode)
	if self._state ~= "close" then return end
	if not forceMode and not UD.setting:isAutoPlayWeather() then
		return
	end
	self._state = "restart"
	self:initWeatherSystem()
    self:playWeather()
end

function WeatherSystem:playControl(mode,weatherId)
	self:stopCurAction()
	if mode == "close" then
		self:closeWeather()
	elseif mode == "restart" then
		self:restartWeather(true)
	elseif mode == "play" then
		if weatherId then
			self._ids = {weatherId}
			self:resetScriptHandler()
			self:playWeather(true)
		end
	end
end

return WeatherSystem